﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using MobileBroadbandLoggingMonitorGUI.UI.Interfaces;
using MobileBroadbandLoggingMonitorUI.Interfaces;
using MobileBroadbandLoggingMonitorUI.UI.Interfaces;
using MobileBroadbandUserBlog.MBLM;
using MobileBroadbandUserBlog.MBLM.Core;
using MobileBroadbandUserBlog.MBLM.Core.Interfaces;
using MobileBroadbandLoggingMonitorGUI.Interfaces;
using MobileBroadbandLoggingMonitorGUI;
using MobileBroadbandLoggingMonitorGUI.UI;

namespace MobileBroadbandLoggingMonitorUI.UI
{
    public class MainFormPresenter
    {
        private IMainFormView _mainFormView;
        private IMobileBroadbandLoggingMonitor _mobileBroadbandLoggingMonitor;
        private IWeb _web;
        private ISettings _settings;
        private IShareInformationPresenter _shareInformationPresenter;

        private IMobileSoftwareLogger _mobileSoftwareLogger;
        private IDialogPresenter _dialogPresenter;

        private string _loggingText = string.Empty;
        private string _allThingsLogged = string.Empty;
        private bool _hasLoggedAnything = false;

        private IApplicationContext _applictionContext;
        private IServerCommunication _serverCommunication;

        private bool _closingHandled = false;
        private bool _isLogging = false;
        IGetProPresenter _getProPresenter;

        public MainFormPresenter(IMainFormView mainFormView, IMobileBroadbandLoggingMonitor mobileBroadbandLoggingMonitor, IShareInformationPresenter shareInformationPresenter, IGetProPresenter getProPresenter, IDialogPresenter dialogPresenter, IWeb web, ISettings settings, IApplicationContext applictionContext, IServerCommunication serverCommunication)
        {
            _mainFormView = mainFormView;
            _dialogPresenter = dialogPresenter;
            _mobileBroadbandLoggingMonitor = mobileBroadbandLoggingMonitor;
            _web = web;
            _settings = settings;
            _shareInformationPresenter = shareInformationPresenter;
            _applictionContext = applictionContext;
            _serverCommunication = serverCommunication;
            _getProPresenter = getProPresenter;
        }


        public void Show()
        {
            _mainFormView.Show();

            SetupEventHandling();
            ResetCounters();
            DetermineandSetupPresentSoftware();
            SetStartUpInformation();
            ShowFirstTimeUseDialog();
        }

        private void SetupEventHandling()
        {
            _mainFormView.StartLoggingClicked += new EventHandler(btnStartLogging_Click);
            _mainFormView.StopLoggingClicked += new EventHandler(btnStopLogging_Click);
            _mainFormView.SolutionClicked += new EventHandler(_lnkSolution_LinkClicked);
            _mainFormView.SuggestionsClicked += new EventHandler(_lnkFeedback_LinkClicked);
            _mainFormView.BlogClicked += new EventHandler(_lnkBlog_LinkClicked);
            _mainFormView.ShareAnonymousInformationClicked += new EventHandler(_mainFormView_ShareAnonymousInformationClicked);
            _mainFormView.Closing += new EventHandler(_mainFormView_Closing);

        }

        void _mainFormView_ShareAnonymousInformationClicked(object sender, EventArgs e)
        {
            if (!_settings.IsProfessionalEdition())
            {
                _getProPresenter.ShowDialog();
                _mainFormView.SetShareAnonymousInformationState(true);
            }
        }

        void _mainFormView_Closing(object sender, EventArgs e)
        {
            if (!_closingHandled)//ugly as hell
            {
                _closingHandled = true;
                StopWatcher();
                if (_hasLoggedAnything && !_mainFormView.GetShareAnonymousInformationState())
                {
                    _shareInformationPresenter.Show(_allThingsLogged);
                }
                _applictionContext.Exit();
            }
        }

        private void DetermineandSetupPresentSoftware()
        {
            if (_mobileBroadbandLoggingMonitor.IsMobileSoftwarePresentOnSystem())
            {
                _mobileSoftwareLogger = _mobileBroadbandLoggingMonitor.GetMobileSoftwareLogger();
            }
            else
            {
                _mobileSoftwareLogger = GetUserDefinedLocationFromUser();
            }
            if (_mobileSoftwareLogger != null)
            {
                _mobileSoftwareLogger.LoggingDetected += new FileChangeDelegate(_mobileSoftwareLogger_LoggingDetected);
            }
        }

        void _mobileSoftwareLogger_LoggingDetected(string file, WatcherChangeTypes changeType)
        {
            //this.Invoke(new FileChangeDelegate(WriteToTextBox), new object[] { file, changeType });
            //this.Invoke(new FileChangeDelegate(WriteStatistics), new object[] { file, changeType });
            WriteToTextBox(file, changeType);
            WriteStatistics(file, changeType);
            
        }

        protected virtual IMobileSoftwareLogger GetUserDefinedLocationFromUser()
        {
            if (UserWantsToChooseCustomLocation())
            {
                return PickCustomLocation();
            }
            return null;
        }

        private IMobileSoftwareLogger PickCustomLocation()
        {
            string path = _dialogPresenter.ShowDirectoryPicker();
            if (path != null)
            {
                return _mobileBroadbandLoggingMonitor.GetMobileSoftwareLogger(path);
            }
            return null;
        }

        private bool UserWantsToChooseCustomLocation()
        {
            return _dialogPresenter.ShowDialog("Mobile Broadband Logging Utility could not locate any programs. Would you like to locate it yourself?", "No program found", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes;
        }

        private void ResetCounters()
        {
            _mainFormView.SetChangePerMinute("...");
            _mainFormView.SetChangePerHour("...");
            _mainFormView.SetChangePerWorkday("...");
        }

        private void SetStartUpInformation()
        {
            string foundSoftwareText = string.Empty;

            foundSoftwareText = "Found mobile broadband software: ";
            if (_mobileSoftwareLogger != null)
            {
                foundSoftwareText += _mobileSoftwareLogger.GetMobileSoftware().GetName();
            }
            else
            {
                foundSoftwareText += "Could not determine.";
                ShowNoSoftwareFound();
                _mainFormView.SetStartLoggingButtonEnabledState(false);
            }
            _mainFormView.SetFoundSoftware(foundSoftwareText);
        }

        protected virtual void ShowNoSoftwareFound()
        {
            _dialogPresenter.ShowDialog("No mobile broadband software was found.\nOnly software from Birdstep, HUAWEI and MWConn is supported at this time.", "Mobile software not found", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void ShowFirstTimeUseDialog()
        {
            if (_settings.IsFirstRun())
            {
                _settings.UpdateFirstRunValue(false);

                _web.ShowWebPage("http://blog.mobilebroadbanduser.eu/page/Thank-you-for-downloading.aspx?from=loggingmonitor");
            }
        }

      
        private void btnStartLogging_Click(object sender, EventArgs e)
        {
            _mainFormView.SetStartLoggingButtonEnabledState(false);
            _mainFormView.SetStopLoggingButtonEnabledState(true);
            _mainFormView.FocusStopButton();
            StartWatcher();
            _hasLoggedAnything = true;
        }

        private void btnStopLogging_Click(object sender, EventArgs e)
        {
            StopWatcher();
            _mainFormView.SetStartLoggingButtonEnabledState(true);
            _mainFormView.SetStopLoggingButtonEnabledState(false);
            _mainFormView.FocusStartButton();
        }

        private void StartWatcher()
        {
            _isLogging = true;
            IMobileSoftware software = _mobileSoftwareLogger.GetMobileSoftware();
            string textToLog = "Started monitoring of " + software.GetName() + " logging " + DateTime.Now.ToString() + " at \"" + software.GetFolderToMonitor() + "\"";
            _allThingsLogged = textToLog + Environment.NewLine + _allThingsLogged;
            _loggingText = textToLog;
            UpdateLoggingBox();
            _mainFormView.SetSolutionLinkVisible(software.HasSolution());
            _mobileSoftwareLogger.StartLogging();
        }

        private void StopWatcher()
        {
            if (_isLogging)
            {
                _isLogging = false;
                IMobileSoftware software = _mobileSoftwareLogger.GetMobileSoftware();
                string textToLog = "Stopped monitoring of " + software.GetName() + " logging " + DateTime.Now.ToString();
                _allThingsLogged = Environment.NewLine + textToLog + Environment.NewLine + _allThingsLogged;
                _loggingText = textToLog + Environment.NewLine + _loggingText;
                _mobileSoftwareLogger.StopLogging();
                UpdateLoggingBox();
                if (_mainFormView.GetShareAnonymousInformationState())
                {
                    _serverCommunication.SendSharedInformationToServer(_loggingText);
                }
            }
        }

        private void WriteToTextBox(string file, WatcherChangeTypes changeType)
        {
            string textToLog = file + "; " + DateTime.Now.ToString() + "; " + changeType.ToString() + Environment.NewLine + _loggingText;
            _allThingsLogged = textToLog + Environment.NewLine + _allThingsLogged;
            _loggingText = textToLog + _loggingText;
            UpdateLoggingBox();
        }

        private void UpdateLoggingBox()
        {
            _mainFormView.SetLoggingText(_loggingText);
        }

        private void WriteStatistics(string file, WatcherChangeTypes changeType)
        {
            WriteStatisticsLabels();
        }

        private void WriteStatisticsLabels()
        {
            IChangeStatistics statistics = _mobileSoftwareLogger.GetChangeStatistics();

            _mainFormView.SetChangePerMinute(statistics.ChangesPerMinute.ToString());
            _mainFormView.SetChangePerHour(statistics.ChangesPerHour.ToString());
            _mainFormView.SetChangePerWorkday(statistics.ChangesPerWorkday.ToString());
        }

        private void _lnkBlog_LinkClicked(object sender, EventArgs e)
        {
            _web.ShowWebPage("http://www.mobilebroadbanduser.eu/");
        }

        private void _lnkSolution_LinkClicked(object sender, EventArgs e)
        {
            IMobileSoftware software = _mobileSoftwareLogger.GetMobileSoftware();
            _web.ShowWebPage(software.GetSolutionURL());
        }

        private void _lnkFeedback_LinkClicked(object sender, EventArgs e)
        {
            _web.ShowWebPage("http://getsatisfaction.com/mobilebroadbanduser/");
        }
    }
}
